from pika.spec import Basic, BasicProperties
from pika.adapters.blocking_connection import BlockingChannel

from src.config import Config
from src.processor.mimo_decode import MimoDecodeAdaptor, MimoDecodeProcessor
from src.processor.mimo_plot import MimoPlotAdaptor, MimoPlotProcessor
from src.result_body import ResultBody

from .consumer import Consumer


class MimoAdaptor(MimoDecodeAdaptor, MimoPlotAdaptor): ...


class MimoConsumer(Consumer):
    def __init__(self, queue: str, ch: BlockingChannel, adaptor: MimoAdaptor) -> None:
        super().__init__(queue, ch, self.__callback)
        self.adaptor = adaptor

    def __callback(
        self,
        channel: BlockingChannel,
        method: Basic.Deliver,
        props: BasicProperties,
        body: bytes,
    ) -> ResultBody:
        processor = self.get_processor(body)
        data_patch = processor.build_data(self.process(processor))
        status_patch = processor.get_success_status_patch()
        return ResultBody(self.app_id, processor.id, data_patch, status_patch)

    @property
    def app_id(self) -> str:
        raise NotImplementedError

    def get_processor(self, body: bytes):
        raise NotImplementedError

    def process(self, processor):
        raise NotImplementedError


class MimoDecodeConsumer(MimoConsumer):
    @property
    def app_id(self):
        return Config().lab_mimo_decode.queue

    def get_processor(self, body: bytes):
        return MimoDecodeProcessor(body)

    def process(self, processor):
        return self.adaptor.mimo_decode(processor)


class MimoPlotConsumer(MimoConsumer):
    @property
    def app_id(self):
        return Config().lab_mimo_plot.queue

    def get_processor(self, body: bytes):
        return MimoPlotProcessor(body)

    def process(self, processor):
        return self.adaptor.mimo_plot(processor)
